H5唤醒APP 简单hacker方法

H5唤醒APP 简单hacker方法

本质上浏览器是通过URLscheme打开APP,一个APP可以设置一个或多个打开自己的URL scheme。类似于zhihu://

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const APPRouter = (router: string) => {
if (isWeiXin()) {
// alert("请点击右上角打开其他浏览器")
return false;
} else {
window.location.href = router

if(isAndroid()){
// 安卓
var t = Date.now()
setTimeout(() => {
if (Date.now() - t < 1200) {
window.location.href = `你app下载域名`
}
}, 1000)
}else{
// 苹果
setTimeout(() => {
window.location.href = `你app下载域名`
}, 250)
setTimeout(() => {
window.location.reload()
}, 1000)
}

return true;
}
}

安卓设置的原理:

如果设置比较小的运行间隔(<30ms),在浏览器或者webview中,应用切换到后台,setInterval会被很明显的延迟执行,比如设置一个运行间隔20ms,总计运行100次的定时器,如果页面一直处于前台,则100次跑完,总耗时与100x20=2000ms不会有太大差异,但页面在后台运行时,此时间会明显超过2000ms。可以利用这一点来实现是否成功打开APP检测及回调。

1
2
3
4
5
6
var t = Date.now()
setTimeout(() => {
if (Date.now() - t < 1200) {
window.location.href = `你app下载域名`
}
}, 1000)

苹果设置的原理:

APP已安装这是没问题的,但如果APP未安装,跳App Store 的请求会失败。 这时可以使用两个定时器

1
2
3
4
5
6
setTimeout(() => {
window.location.href = `你app下载域名`
}, 250)
setTimeout(() => {
window.location.reload()
}, 1000)

Iframe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var ifm = document.createElement('iframe');

ifm.setAttribute('src', wakeupUrl);
ifm.setAttribute('style', 'display:none');
document.body.appendChild(ifm);
onBeforeWakeup && onBeforeWakeup();

var currentTime = Date.now();

setTimeout(function() {
var nowTime = Date.now();
if (nowTime - currentTime < 1050) {
// 回调
onWakeupFail && onWakeupFail();
}
}, 1000);

引导页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const H5ToApp = () => {
const div = document.createElement('div');
document.body.appendChild(div);

let template = `
<div class="h5_toweixin" style="z-index: 9999;position: absolute;width: 100%;top: 0px;left: 0;height: 100%;">
<img src="/images/h5-weixin.png" alt="引导到微信"/>
</div>`
const bodyScroll = (event: any) => {
event.stopPropagation();
event.preventDefault();
}
div.appendChild(parseElement(template))
window.addEventListener('touchmove', bodyScroll);
document.body.style.position = 'fixed';
document.addEventListener("click", fn)
function fn(){
if (div.parentNode) {
document.body.style.position = 'static';
window.removeEventListener('touchmove', bodyScroll);
document.removeEventListener('click',fn);
div.parentNode.removeChild(div);
}
}
}

const parseElement = (htmlString: string) => {
return new DOMParser().parseFromString(htmlString, 'text/html').body.childNodes[0]
}

export {H5ToApp}

总结

坑很多,问题主要在安卓上,会有各种兼容问题,机型浏览器众多。当然ios也有。

知乎的解决办法是,提供两个按钮,一个下载,一个打开APP,让用户自己选。

参考

链接:https://www.jianshu.com/p/7645ad94840d

感谢你的打赏哦!